/* 
 * File:   Opengl.cpp
 * Author: Marco Ambu
 * 
 * Created on October 1, 2010, 9:32 AM
 */

#include "Opengl.h"
#include "ReshapeHandler.h"
#include "DisplayHandler.h"
#include "KeyboardHandler.h"
#include <GL/glut.h>

ReshapeHandler* Opengl::reshapeHandler_ = NULL;
DisplayHandler* Opengl::displayHandler_ = NULL;
KeyboardHandler* Opengl::keyboardHandler_ = NULL;
ExitHandler* Opengl::exitHandler_ = NULL;

Opengl::Opengl(int* argc, char** argv)
{
  glutInit(argc, argv);
  exitHandler_ = this;
}

Opengl::~Opengl()
{
  reshapeHandler_ = NULL;
  displayHandler_ = NULL;
  keyboardHandler_ = NULL;
  exitHandler_ = NULL;
}

void Opengl::run()
{
  // register callback handlers
  glutReshapeFunc(&Opengl::onReshape);
  glutDisplayFunc(&Opengl::onDisplay);
  glutKeyboardFunc(&Opengl::onKeyboard);
  glutSpecialFunc(&Opengl::onSpecial);

  glutMainLoop();
}

void Opengl::registerReshapeHandler(ReshapeHandler* handler)
{
  reshapeHandler_ = handler;
}

void Opengl::registerDisplayHandler(DisplayHandler* handler)
{
  displayHandler_ = handler;
}

void Opengl::registerKeyboardHandler(KeyboardHandler* handler)
{
  keyboardHandler_ = handler;
}

void Opengl::onExitEvent()
{
  reshapeHandler_ = NULL;
  displayHandler_ = NULL;
  keyboardHandler_ = NULL;
}

//static
void Opengl::onReshape(int width, int height)
{
  if (reshapeHandler_)
    reshapeHandler_->onReshapeEvent(width, height);
}

//static
void Opengl::onDisplay()
{
  if (displayHandler_)
    displayHandler_->onDisplayEvent();
}

//static
void Opengl::onKeyboard(unsigned char key, int x, int y)
{
  if (key == 27)
  {
    if (exitHandler_)
    {
      exitHandler_->onExitEvent();
      exitHandler_ = NULL;
    }
    exit(0);
  }

  if (keyboardHandler_)
    keyboardHandler_->onKeyEvent(key, x, y);
}
//static
void Opengl::onSpecial(int key, int x, int y)
{
  if (keyboardHandler_)
    keyboardHandler_->onSpecialEvent(key, x, y);
}
